import {
	Injectable,
	NotFoundException,
	BadRequestException,
} from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import * as bcrypt from "bcrypt";
import { User } from "./entities/user.entity";
import { CreateUserDto } from "./dto/create-user.dto";
import { UpdateUserDto } from "./dto/update-user.dto";

@Injectable()
export class UserService {
	constructor(
		@InjectRepository(User)
		private userRepository: Repository<User>
	) {}

	async findAll(query: any): Promise<[User[], number]> {
		const { username, status, page = 1, limit = 10 } = query;

		const queryBuilder = this.userRepository.createQueryBuilder("user");

		if (username) {
			queryBuilder.andWhere("user.username LIKE :username", {
				username: `%${username}%`,
			});
		}

		if (status) {
			queryBuilder.andWhere("user.status = :status", { status });
		}

		queryBuilder.skip((page - 1) * limit);
		queryBuilder.take(limit);
		queryBuilder.orderBy("user.id", "DESC");

		return queryBuilder.getManyAndCount();
	}

	async findOne(id: number): Promise<User> {
		const user = await this.userRepository.findOne({ where: { id } });
		if (!user) {
			throw new NotFoundException(`用户ID为${id}的用户不存在`);
		}
		return user;
	}

	async findByUsername(username: string): Promise<User> {
		const user = await this.userRepository.findOne({ where: { username } });
		return user;
	}

	async create(createUserDto: CreateUserDto): Promise<User> {
		const { username, password } = createUserDto;

		// 检查用户名是否已存在
		const existingUser = await this.findByUsername(username);
		if (existingUser) {
			throw new BadRequestException("用户名已存在");
		}

		// 密码加密
		const salt = await bcrypt.genSalt();
		const hashedPassword = await bcrypt.hash(password, salt);

		const user = this.userRepository.create({
			...createUserDto,
			password: hashedPassword,
		});

		return this.userRepository.save(user);
	}

	async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {
		const user = await this.findOne(id);

		// 如果更新密码，且密码不是已经加密的格式（以$2b$开头）
		if (updateUserDto.password && !updateUserDto.password.startsWith("$2b$")) {
			const salt = await bcrypt.genSalt();
			updateUserDto.password = await bcrypt.hash(updateUserDto.password, salt);
		}

		Object.assign(user, updateUserDto);
		return this.userRepository.save(user);
	}

	async updatePoints(id: number, points: number): Promise<User> {
		const user = await this.findOne(id);
		user.points += points;
		return this.userRepository.save(user);
	}

	async remove(id: number): Promise<void> {
		const user = await this.findOne(id);
		await this.userRepository.remove(user);
	}

	async validateUser(username: string, password: string): Promise<any> {
		const user = await this.findByUsername(username);
		console.log("验证用户:", username);
		console.log("数据库中的密码哈希:", user?.password);
		console.log("输入的密码:", password);

		if (user) {
			const isMatch = await bcrypt.compare(password, user.password);
			console.log("密码比对结果:", isMatch);
			if (isMatch) {
				const { password, ...result } = user;
				return result;
			}
		}
		return null;
	}
}
